import {getCurrentInstance, onMounted, reactive, Ref, ref} from 'vue';
import axios from 'axios';
// import * as egm96 from 'egm96-universal';
import {useStore} from 'vuex';
import {FmMapManager, PathConfig} from '@/views/monitor/fmmapmanager';
import monitorConfig, {imgPathConfig} from './monitorConfig';
import {planeM} from '@/utils/planeModel';
import bigDatas from '@/utils/planes.json';
import {getMonitorInfo} from '@/api';

export type Poly = {
  show: () => void;
  hide: () => void;
  setPath: (path: any) => void;
  getEntity: () => any;
};

// 处理航线飞行及回放
export const useFmManagerHelper = ({
  feimaManager,
  CMapRef,
  data = {title: '', local_id: '', serial_no: ''},
  watchData,
}: {
  feimaManager: Ref<any>;
  CMapRef: Ref<any>;
  data?: {title: string; local_id: string; serial_no: string};
  watchData: any;
}) => {
  const $http = getCurrentInstance()?.appContext.config.globalProperties.$http;
  const viewer = ref();
  const flightMission = ref<FlightMission | null>();
  const softwareCode = ref<string>('');
  const missionData = ref<{
    title?: string;
    local_id?: string;
    serial_no?: string;
  }>();
  const liveUrls = ref();
  const planeInfo = ref();
  const loading = ref(false);
  onMounted(() => {
    missionData.value = data;

    monitorConfig.local_id = data.local_id;
    softwareCode.value = data.serial_no;
    init();
  });

  const init = async () => {
    if (!missionData.value) {
      return;
    }

    let monitorData: any;
    const moveToTarget = false;
    // 传了local_id, 则获取flightMission。
    if (missionData.value.local_id) {
      monitorData = await getDeviceInfo({
        local_id: missionData.value.local_id,
      });
    }
    if (softwareCode.value) {
      monitorData = await getDeviceInfo({
        uas_serial_id: softwareCode.value,
      });
    }
    if (monitorData.data) {
      liveUrls.value = monitorData.live;
      planeInfo.value = {
        plane: monitorData.plane,
        plane_key: monitorData.plane_key,
      };
      flightMission.value = monitorData.data as FlightMission;
      monitorConfig.flight_data = monitorData.data as FlightMission;

      // 只传了local_id，且飞机还在飞，则更新softwareCode
      if (!softwareCode.value && monitorData.is_mission_flying) {
        softwareCode.value = flightMission.value.uas_serial_id;
      }
    }
    // 有softwareCode，则尝试获取飞机websocket
    if (softwareCode.value) {
      const res = await getMonitorInfo(softwareCode.value);
      // eslint-disable-next-line no-shadow
      const {data} = res.data;
      // eslint-disable-next-line camelcase
      const tb_id = data?.data?.tb_id;
      monitorConfig.wsMessageFunc = () =>
        `{"attrSubCmds":[],"tsSubCmds":[{"entityType":"DEVICE","entityId":"${tb_id}","scope":"LATEST_TELEMETRY","cmdId":1}],"historyCmds":[]}`;
      monitorConfig.url = data.ws_url;
    }

    await initMap();

    if (flightMission.value) {
      initFmManager();
      try {
        initAirline();
      } catch (err) {
        console.log(err);
      }
    }
  };
  const isHistory = ref(false);
  const CMap = ref();
  const store = useStore();

  // 地球初始化相关
  const initMap = async () => {
    await CMapRef.value.init();
    const {earth} = CMapRef.value;
    viewer.value = earth.viewer;
    CMap.value = viewer.value.CMap;
    // earth.setCompass(true)
    // 移动到链接坐标
    const {location} = store.state;
    if (location && !flightMission.value) {
      earth.viewer.flyTo([location.lat, location.lng, 500]);
    }

    // drawHomeModel()
  };
  // FmMapManager初始化, 处理无人机的监听、回放及航线初始
  const initFmManager = () => {
    (PathConfig as any).setConfigs(imgPathConfig); // 图片路径

    feimaManager.value = new FmMapManager(monitorConfig);
    feimaManager.value.createMonitor();
    feimaManager.value.onPlaneMove = () => {
      onPlaneMove();
    };
    // eslint-disable-next-line no-shadow
    feimaManager.value.clearAirLinePath = (data: any) => {
      flyingAirline.value.setPath(data);
      const position = data[data.length - 1];
      feimaPlaneModel.value.moveTo({position, duration: 300});
    };
  };
  // 监听飞机位置改变
  const flyingAirline = ref();
  const feimaPlaneModel = ref();

  const onPlaneMove = () => {
    drawFlyingModel(); // 处理飞机模型

    drawFlyingAirline(); // 处理在飞的航线
  };
  // 通过local_id获取flightMission
  type FlightMissionApiData = {
    data: object | null;
    is_mission_flying: boolean;
    live?: Object | null;
    plane?: Object;
    plane_key?: Object;
  };
  const getDeviceInfo = (params: any) =>
    new Promise<FlightMissionApiData>((resolve, reject) => {
      if (!missionData.value) {
        reject();
        return;
      }
      // eslint-disable-next-line promise/catch-or-return
      $http.get('/flightMission/monitor', params).then((res: any) => {
        if (res && res.data) {
          store.commit('setLocalId', res.data.data.local_id);
          if (!res.data.is_mission_flying) {
            loading.value = true;
            // eslint-disable-next-line promise/catch-or-return
            $http
              .get('/flightLog/getDecode', {
                flight_mission_id: res.data.data.id,
              })
              .then((urlRes: any) => {
                res.data.data.flight_log = {};
                res.data.data.flight_log.packages = urlRes.data;
                loading.value = false;
                resolve(res.data);
              });
          } else {
            resolve(res.data);
          }
        } else {
          resolve({data: null, is_mission_flying: false});
        }
      });
    });
  /**
   * 根据url获取到历史数据
   * @param url 历史数据的url
   * @returns
   */

  const getFlightLogData = (url: string) =>
    new Promise((resolve, reject) => {
      try {
        axios
          .get(url)
          .then((response) => {
            resolve(response.data);
          })
          .catch((error) => {
            reject(error);
          });
      } catch (err) {
        reject(err);
      }
    });
  const startPoint = ref();
  const landingPoint = ref();

  const polyline = ref<Poly>();
  // 初始化航线
  // 处理初始航线及起飞点、降落点标记
  const initAirline = () => {
    const mockPath = feimaManager.value?.wgs84Airline?.path?.map((position: any) => ({
      lng: position[0],
      lat: position[1],
      alt: position[2],
    }));

    // 初始航线
    polyline.value = new CMap.value.Polyline({
      viewer: viewer.value,
      path: [],
      strokeColor: feimaManager.value.wgs84Airline.color,
      strokeWeight: feimaManager.value.wgs84Airline.width,
    }) as Poly;
    polyline.value.setPath(mockPath);
    CMapRef.value.zoomToFit();
    polyline.value.hide = function () {
      this.getEntity().show = false;
    };
    polyline.value.show = function () {
      this.getEntity().show = true;
    };
    // 初始起飞点

    const startConfig = feimaManager.value.wgs84Markers[0];
    startPoint.value = new CMap.value.Marker({
      viewer: viewer.value,
      position: {
        lat: startConfig.lnglat[1],
        lng: startConfig.lnglat[0],
        alt: startConfig.lnglat[2],
      },
      icon: startConfig.icon,
      width: 50,
      height: 100,
      offset: [0, 0],
    });
    // 初始降落点
    const landConfig = feimaManager.value.wgs84Markers[1];
    landingPoint.value = new CMap.value.Marker({
      viewer: viewer.value,
      position: {
        lat: landConfig.lnglat[1],
        lng: landConfig.lnglat[0],
        alt: landConfig.lnglat[2],
      },
      icon: landConfig.icon,
      width: 20,
      height: 20,
      offset: [0, 0],
    });
    if (flightMission?.value?.flight_log?.packages) {
      setTimeout(() => {
        isHistory.value = true;
        watchData(isHistory.value);
      }, 1500);
    } else {
      watchData(isHistory.value);
    }
  };
  // 航线绘制及更新
  const drawFlyingAirline = () => {
    if (!flyingAirline.value) {
      flyingAirline.value = new CMap.value.Polyline({
        viewer: viewer.value,
        path: [],
        strokeColor: feimaManager.value.flyingAirline.color,
        strokeWeight: feimaManager.value.flyingAirline.width,
      });
      flyingAirline.value.setPath([]);
    } else {
      const path = flyingAirline.value.getPath();

      const {latitude, longitude, altitude} = feimaManager.value.fmMonitor.wgs84CurrentPosition;

      path.push({lat: latitude, lng: longitude, alt: altitude || 0});
      flyingAirline.value.setPath(path);
    }
  };
  // 测试模型绘制
  const drawHomeModel = () => {
    const {location} = store.state;
    // eslint-disable-next-line no-new
    new CMap.value.Model({
      id: 10,
      viewer: viewer.value,
      url: '/earthmap/res/GroundVehicle/V100.glb',
      scale: 0.01,
      isTracked: false,
      maximumScale: 1,
      position: {
        lat: location.lat,
        lng: location.lng,
        alt: 450,
      },
      attitude: {
        roll: 0,
        yaw: 50,
        pitch: 0,
      },
    });
  };
  // 判断当前模型是否为mavic
  const isNotMavic = (): boolean => {
    const url = planeM.getPlaneModel(flightMission.value?.plane_type || '')?.toUpperCase();

    if (url.indexOf('MAVIC') === -1) {
      return true;
    }
    return false;
  };
  // 飞机模型绘制及更新
  const drawFlyingModel = () => {
    const currentPosition = feimaManager.value.fmMonitor.wgs84CurrentPosition;

    // 椭球高转wgs84海拔高
    currentPosition.altitude = egm96.ellipsoidToEgm96(
      currentPosition.latitude,
      currentPosition.longitude,
      currentPosition.altitude,
    );

    if (!feimaPlaneModel.value) {
      if (currentPosition && currentPosition.latitude && parseFloat(currentPosition.latitude) != 0) {
        const url = planeM.getPlaneModel(flightMission.value?.plane_type || '');
        const scale = !isNotMavic() ? 0.001 : 0.05;
        feimaPlaneModel.value = new CMap.value.Model({
          id: 1,
          viewer: viewer.value,
          url,
          scale,
          isTracked: true,
          maximumScale: 1,
          position: {
            lat: currentPosition.latitude,
            lng: currentPosition.longitude,
            alt: currentPosition.altitude || 0,
          },
          attitude: {
            roll: 0,
            yaw: 50,
            pitch: 0,
          },
        });
      }
    } else {
      const lastPosition = feimaPlaneModel.value.position;

      const position = {
        lat: currentPosition.latitude,
        lng: currentPosition.longitude,
        alt: currentPosition.altitude || 0,
      };

      // feimaPlaneModel.value.setPosition(position);
      feimaPlaneModel.value.moveTo({position, duration: 300});
    }

    const flightPanel = feimaManager.value.fmMonitor.flightPanelDatas;
    // eslint-disable-next-line prefer-const
    let {yaw, pitch, roll} = flightPanel;
    // 非 mavic 模型现在水平是相反，所以需要-180度进行校准
    // 校准后影响了俯仰，所以俯仰取负
    if (isNotMavic()) {
      yaw -= 180;
      pitch = -pitch;
    }
    feimaPlaneModel.value && feimaPlaneModel.value.setAttitude({yaw, pitch, roll});
  };
  const backPlayFunc = (funName: Number, percent: Number = 0, nowTime: Number = 0, allTime: Number = 0) => {
    switch (funName) {
      case 0:
        feimaManager.value.fmMonitor.pausePlayBack();
        break;
      case 1:
        feimaManager.value.fmMonitor.openPlayBack(allTime);
        break;
      case 2:
        // eslint-disable-next-line promise/catch-or-return
        feimaManager.value.fmMonitor.setPlaybackProgress(percent).then((res: any) => {
          const path: {lat: any; lng: any; alt: any}[] = [];
          // eslint-disable-next-line no-shadow
          feimaManager.value.wgs84FlyingAirline.path.forEach((res: any) => {
            // 椭球高转wgs84海拔高
            const alt = egm96.ellipsoidToEgm96(res[1], res[0], res[2]);
            path.push({lat: res[1], lng: res[0], alt});
          });
          if (!flyingAirline.value) {
            flyingAirline.value = new CMap.value.Polyline({
              viewer: viewer.value,
              path: [],
              strokeColor: feimaManager.value.flyingAirline.color,
              strokeWeight: feimaManager.value.flyingAirline.width,
            });
            flyingAirline.value.setPath([]);
          } else {
            flyingAirline.value.setPath(path);
          }
        });
        break;
      default:
        break;
    }
  };

  // const markers = reactive<any[]>([])
  const drawMarkers = () => {
    bigDatas.data.data.forEach((device: any) => {
      const posi = device._source.point;
      const options = {
        viewer: viewer.value,
        position: {
          lat: posi.lat + Math.random() * 0.00001,
          lng: posi.lon + Math.random() * 0.00001,
          alt: 100,
        },
        icon: '/static/img/feimaToDetail/cloudplay/plane_D200.png',
        width: 50,
        height: 50,
      };
      const marker = createMarker(options);
      // markers.push(marker)
    });
  };

  const createMarker = (markerOptions: MarkerOptions) => new CMap.value.Marker(markerOptions);
  return {
    flightMission,
    softwareCode,
    startPoint,
    landingPoint,
    polyline,
    feimaPlaneModel,
    backPlayFunc,
    isHistory,
    liveUrls,
    planeInfo,
    loading,
  };
};
